package com.greate.shiro.springbootshirodemo.config;

import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author Administrator
 */
@Configuration
public class ShiroConfig {

	@Bean("defaultAdvisorAutoProxyCreator")
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
		defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
		return defaultAdvisorAutoProxyCreator;
	}


	@Bean("authorizationAttributeSourceAdvisor")
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor =
			new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}

	/**
	 * 路径拦截
	 *
	 * @param securityManager 安全管理
	 * @return 回执
	 */
	@Bean("shiroFilterFactoryBean")
	public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager securityManager) {
		ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
		bean.setSecurityManager(securityManager);

		// 设置登录地址
		bean.setLoginUrl("/user/login");
		// 没有权限情况下返回的地址
		bean.setUnauthorizedUrl("/unAuth/");
		// jwt 过滤器
		Map<String, Filter> filters = new LinkedHashMap<>();
		filters.put("jwt", new JwtAuthFilter());
		bean.setFilters(filters);
		// 路径过滤
		Map<String, String> filterRuleMap = new LinkedHashMap<>();
		filterRuleMap.put("/user/login", "anon");
		filterRuleMap.put("/api/**", "anon");
		filterRuleMap.put("/v2/**", "anon");
		filterRuleMap.put("/doc.html", "anon");
		filterRuleMap.put("/webjars/**", "anon");
		filterRuleMap.put("/swagger-resources/**", "anon");
		filterRuleMap.put("/**", "jwt");
		bean.setFilterChainDefinitionMap(filterRuleMap);
		return bean;
	}

	@Bean("securityManager")
	public SecurityManager securityManager(@Qualifier("authorizingRealm") AuthorizingRealm authorizingRealm) {
		DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
		defaultWebSecurityManager.setRealm(authorizingRealm);
		return defaultWebSecurityManager;
	}

	/**
	 * 自定义realm
	 *
	 * @param credentialsMatcher 密码校验
	 * @return 回执
	 */
	@Bean("authorizingRealm")
	public AuthorizingRealm authorizingRealm(@Qualifier("credentialsMatcher") CredentialsMatcher credentialsMatcher) {
		CustomAuthorizingRealm myRealm = new CustomAuthorizingRealm();
		myRealm.setCredentialsMatcher(credentialsMatcher());
		return myRealm;
	}

	/**
	 * 配置密码比较器
	 *
	 * @return 比较规则
	 */
	@Bean("credentialsMatcher")
	public CredentialsMatcher credentialsMatcher() {
		return new CustomCredentialsMatcher();
	}


}
